home *** CD-ROM | disk | FTP | other *** search
- #include "quicky.hpp"
- #include "xbmtools.h"
- #include "xcbitmap.h"
- #include "xlib_all.h"
-
- /* these are here instead of the header file because they're not part
- of the library interface */
-
- // rol al,1
- #define ROL_AL 0xc0d0
- // mov [esi + disp8], imm8
- #define SHORT_STORE_8 0x46c6
- // mov [esi + disp32], imm8
- #define STORE_8 0x86c6
- // mov [esi + disp8], imm16
- #define SHORT_STORE_32 0x46c7
- // mov [esi + disp32], imm16
- #define STORE_32 0x86c7
- // adc esi, imm8
- #define ADC_SI_IMMED 0xd683
- // out dx, al
- #define OUT_AL 0xee
- // ret
- #define RETURN 0xc3
- // 16-bit prefix
- #define WORD_PREFIX 0x66
-
-
-
- int output_used = 0;
-
-
-
- uchar ColumnMask[]= { 0x11,0x22,0x44,0x88 };
-
- /*
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; _x_put_cbitmap
- ;
- ; Displays a compiled bitmap generated by x_compile_bitmap at given
- ; coordinates, on a given screen page.
- ;
- ; C near-callable as:
- ; void x_put_cbitmap (int XPos, int YPos,
- ; unsigned int PageOffset, char far * Sprite);
- ; ax, bx, cx, and dx are squashed like insignificant insects.
- */
-
- extern void asm_x_put_cbitmap(ushort XPos, ushort YPos, ushort PageOffset, char * Sprite);
-
- #pragma aux asm_x_put_cbitmap= \
- "push esi" \
- \
- "mov edx, [ScrnLogicalByteWidth]" \
- "mul edx" \
- "and ebx, 0x0ffff" \
- "mov esi, ebx" \
- "sar esi, 2" \
- "and eax, 0x0ffff" \
- "add esi, eax" \
- "and ecx, 0x0ffff" \
- "add esi, ecx" \
- "add esi, 128" \
- "add esi, 0xa0000" \
- \
- "and ebx, 3" \
- "mov ah, ColumnMask[ebx]" \
- \
- "mov dx, 0x3c4" \
- "mov al, 0x02" \
- "out dx, ax" \
- "inc dx" \
- "mov al, ah" \
- \
- "call edi" \
- \
- "pop esi" \
- parm [bx] [ax] [cx] [edi] \
- modify [edx];
-
-
- // if asm_x_put_cbitmap was called directly from outside code, the compiler
- // couldn't find the function
- void x_put_cbitmap(ushort XPos, ushort YPos, ushort PageOffset, char * Sprite)
- {
- asm_x_put_cbitmap(XPos,YPos,PageOffset,Sprite);
- }
-
-
- // converted these to functions because otherwise the compiler optimized code
- // too well, having some bad/buggy side-effects in x_compile_bitmap
- void Emitb(char * output, uchar x)
- {
- *(output + output_used) = x;
- output_used++;
- }
-
- void Emitw(char * output, ushort x)
- {
- *(output + output_used) = x & 255;
- *(output + output_used+1) = x >> 8;
- output_used += 2;
- }
-
- // emit double word
- void Emitd(char * output, ulong x)
- {
- *(output + output_used) = x & 255;
- *(output + output_used+1) = x >> 8;
- *(output + output_used+2) = x >> 16;
- *(output + output_used+3) = x >> 24;
- output_used += 4;
- }
-
- int x_compile_bitmap (int logical_screen_width, char * bitmap, char * output)
- {
- long pos;
- int pix0, pix1, pix2, pix3, numpix;
- int column = 0, set_column = 0;
- int scanx = 0, scany = 0;
-
- int height = LBMHeight(bitmap);
- int width = LBMWidth(bitmap);
- int margin = width - 1;
- int margin2 = margin - 4;
- int margin4 = margin - 12;
-
- output_used = 0; // must reset this on every compile
-
- while (column < 4) {
- numpix = 1;
- pix0 = LBMGetPix(scanx, scany, bitmap);
- if (pix0 != 0) {
- if (set_column != column) {
- do {
- Emitw (output, ROL_AL);
- Emitw (output, ADC_SI_IMMED);
- Emitb (output, 0);
- set_column++;
- } while (set_column != column);
- Emitb (output, OUT_AL);
- }
- if (scanx <= margin2) {
- pix1 = LBMGetPix(scanx + 4, scany, bitmap);
- if ((pix1 != 0)
- &&(scanx <= margin4)) {
- numpix = 2;
- pix2 = LBMGetPix(scanx + 8, scany, bitmap);
- pix3 = LBMGetPix(scanx + 12, scany, bitmap);
- if ((pix2 != 0) && (pix3 != 0)) {
- numpix = 4;
- }
- }
- }
- pos = (scany * logical_screen_width) + (scanx >> 2) - 128;
- if ((pos >= -128) && (pos <= 127)) {
- if (numpix == 1) {
- Emitw (output, SHORT_STORE_8);
- Emitb (output, pos);
- Emitb (output, pix0);
- } else {
- if( numpix != 4 )
- Emitb (output, WORD_PREFIX);
- Emitw (output, SHORT_STORE_32);
- Emitb (output, pos);
- Emitb (output, pix0);
- Emitb (output, pix1);
- if (numpix == 4) {
- Emitb (output, pix2);
- Emitb (output, pix3);
- }
- }
- } else {
- if (numpix == 1) {
- Emitw (output, STORE_8);
- Emitd (output, pos);
- Emitb (output, pix0);
- } else {
- if( numpix != 4 )
- Emitb (output, WORD_PREFIX);
- Emitw (output, STORE_32);
- Emitd (output, pos);
- Emitb (output, pix0);
- Emitb (output, pix1);
- if (numpix == 4) {
- Emitb (output, pix2);
- Emitb (output, pix3);
- }
- }
- }
- }
- scanx += (numpix << 2);
- if (scanx > margin) {
- scanx = column;
- scany++;
- if (scany == height) {
- scany = 0;
- column++;
- scanx=column; // this was missing in original
- // and caused a bug: the first
- // line of bitmap was shifted
- // right one pixel
- }
- }
- }
- Emitb(output, RETURN);
- return(output_used);
- }
-
-
- int x_sizeof_cbitmap (int logical_screen_width, char * bitmap)
- {
- int pix0, pix1, pix2, pix3, numpix, pos;
- int column = 0, set_column = 0;
- int scanx = 0, scany = 0;
- int output_used = 1;
-
- int height = LBMHeight(bitmap);
- int width = LBMWidth(bitmap);
- int margin = width - 1;
- int margin2 = margin - 4;
- int margin4 = margin - 12;
-
- while (column < 4) {
- numpix = 1;
- pix0 = LBMGetPix(scanx, scany, bitmap);
- if (pix0 != 0) {
- if (set_column != column) {
- do {
- output_used += 5;
- set_column++;
- } while (set_column != column);
- output_used++;
- }
- if (scanx <= margin2) {
- pix1 = LBMGetPix(scanx + 4, scany, bitmap);
- if ((pix1 != 0)
- &&(scanx <= margin4)) {
- numpix = 2;
- pix2 = LBMGetPix(scanx + 8, scany, bitmap);
- pix3 = LBMGetPix(scanx + 12, scany, bitmap);
- if ((pix2 != 0) && (pix3 != 0)) {
- numpix = 4;
- }
- }
- }
- pos = (scany * logical_screen_width) + (scanx >> 2) - 128;
- if ((pos >= -128) && (pos <= 127)) {
- if (numpix == 1) {
- output_used += 4;
- } else {
- if( numpix != 4 )
- output_used++;
- output_used += 5;
- if (numpix == 4)
- output_used += 2;
- }
- } else {
- if (numpix == 1) {
- output_used += 7;
- } else {
- if( numpix !=4 )
- output_used++;
- output_used += 8;
- if (numpix == 4)
- output_used += 2;
- }
- }
- }
- scanx += (numpix << 2);
- if (scanx > margin) {
- scanx = column;
- scany++;
- if (scany == height) {
- scany = 0;
- column++;
- scanx=column; // this was missing in original
- // and caused a bug: the first
- // line of bitmap was shifted
- // right one pixel
- }
- }
- }
- return(output_used);
- }
-
-